#ifndef EEPROM
#define	EEPROM

// ***************************************************************************
// CHANGE LOG
//
// ***************************************************************************

// ***************************************************************************
// ***************************************************************************
// Section: Includes
// ***************************************************************************
// ***************************************************************************
#include <string>
#include "Spi.h"

// ***************************************************************************
// ***************************************************************************
// Section: Constants & Data Types
// ***************************************************************************
// ***************************************************************************

/*! \brief Allows reading and writing to an external EEPROM
 *
 *  <b>EEPROM Memory Layout</b>
 * <table>
 *	<tr>
 *		<td style="font-weight: bold; text-align: center;">Address</td>
 *		<td style="font-weight: bold; text-align: center;">Length (Bytes)</td>
 *		<td style="font-weight: bold; text-align: center;">Data Type</td>
 *		<td style="font-weight: bold; text-align: center;">Information</td>
 *		<td style="font-weight: bold; text-align: center;">Notes</td>
 *	</tr>
 *	<tr>
 *		<td>0 (0x0000)</td>
 *		<td style="text-align: center;">2</td>
 *		<td>unsigned char</td>
 *		<td>Module Type</td>
 *		<td>
 *			Two ASCII character module type.\n
 *			Example: A FFD cone has a module type "06". So 06 will be
 *			stored.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>2 (0x0002)</td>
 *		<td style="text-align: center;">2</td>
 *		<td>unsigned char</td>
 *		<td>Module Number</td>
 *		<td>
 *			Two ASCII character module number.\n
 *			Example: 1st Cone = 01, 2nd cone = 02\n
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>4 (0x0004)</td>
 *		<td style="text-align: center;">10</td>
 *		<td>unsigned char</td>
 *		<td>Module Serial Number</td>
 *		<td>10 character serial number stored as ASCII characters</td>
 *	</tr>
 *	<tr>
 *		<td>14 (0x000E)</td>
 *		<td style="text-align: center;">1</td>
 *		<td>unsigned char</td>
 *		<td>Sensor Count</td>
 *		<td>
 *			Binary sensor count.\n
 *			Ex:\n
 *			0x01 = 1 sensor
 *			0x04 = 4 sensors
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>15 (0x000F)</td>
 *		<td style="text-align: center;">10</td>
 *		<td>unsigned char</td>
 *		<td>ADC Channels</td>
 *		<td>
 *			10-byte binary list of configured ADC channels with the
 *			following flags:\n
 *			0xFF: Internal Use\n
 *			0xFE: Internal Use\n
 *			0xFD: Internal Use\n
 *			0xFC: Ignore Channel\n
 *			0x00 - 0x09: Channel In Use\n
 *			\n
 *			The first three bytes of this field are always 0xFDFEFF.\n
 *			These three channels are used internally for calibration
 *			purposes are should not be read by uphole software.\n
 *			\n
 *			The order that channels appear are also relevent. The location
 *			of a channel is mapped to the location of the sensor as given
 *			below.\n
 *			\n
 *			For example, if 0x00 is in the fifth byte of the channels
 *			array and 0x02 is in the fifth byte of the sensors array,
 *			then the second sensor is mapped to ADC channel 0.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>25 (0x0019)</td>
 *		<td style="text-align: center;">10</td>
 *		<td>unsigned char</td>
 *		<td>ADC Sensors</td>
 *		<td>
 *			10-byte binary list of configured ADC sensors with the
 *			following flags:\n
 *			0xFF: Ignore Channel\n
 *			0x00 - 0x09: Sensor In Use\n
 *			\n
 *			The first three bytes of this field are always 0xFFFFFF.\n
 *			These three sensors are used internally for calibration
 *			purposes are should not be read by uphole software.\n
 *			\n
 *			The order that sensors appear is also relevent. The location
 *			of a channel is mapped to the location of the sensor as given
 *			below.\n
 *			\n
 *			For example, if 0x00 is in the fifth byte of the channels
 *			array and 0x02 is in the fifth byte of the sensors array,
 *			then the second sensor is mapped to ADC channel 0.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>35 (0x0023)</td>
 *		<td style="text-align: center;">1</td>
 *		<td>unsigned char</td>
 *		<td>Hardware Type</td>
 *		<td>
 *			Binary byte representing the hardware type.\n
 *			1 = dual board\n
 *			2 = single board
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>36 (0x0024)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 0 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>76 (0x004C)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 1 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>116 (0x0074)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 2 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>156 (0x009C)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 3 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>196 (0x00C4)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 4 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>236 (0x00EC)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 5 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>276 (0x0114)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 6 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>316 (0x013C)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 7 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>356 (0x0164)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 8 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 *	<tr>
 *		<td>396 (0x018C)</td>
 *		<td style="text-align: center;">40</td>
 *		<td>10x32-bit floating point</td>
 *		<td>Channel 9 Calibration Factors</td>
 *		<td>
 *			10 element array of 32-bit IEEE floating point values
 *			representing the five calibration factors and five units
 *			for the ADC channel.\n
 *			\n
 *			Used by uphole software.
 *		</td>
 *	</tr>
 * </table>
 *
 *  Author: Eric Jordan<br />
 *  Email: ejordan@ara.com<br />
 *  Phone: (802) 728-7477<br />
 *  Last Modified: 2013-03-09
 */

class Eeprom
{
  public:
	// Data Structures and Enums

	/*! \brief EEPROM Commands
	 */
	enum class Commands
	{
		WriteStatusRegister = 1, /*!< 0000 0001 : WRSR */
				Write = 2, /*!< 0000 0010 : WRITE */
				Read = 3, /*!< 0000 0011 : READ */
				WriteDisable = 4, /*!< 0000 0100 : WRDI */
				ReadStatusRegister = 5, /*!< 0000 0101 : RDSR */
				WriteEnable = 6 /*!< 0000 0110 : WREN */
	};


	// Constructors
	Eeprom(Spi *spi);

	// Destructor
	virtual ~Eeprom();

	// Methods
	void Write(UINT32 address, unsigned char data);
	void Write(UINT32 address, const unsigned char *buffer, int length);
	void Write(
			UINT32 address,
			const unsigned char *buffer,
			int index,
			int length);
	void Write(UINT32 address, std::string data);

	unsigned char ReadStatus();
	unsigned char Read(UINT32 address);
	void Read(UINT32 address, std::string *buffer);
	void Read(UINT32 address, unsigned char *buffer, int length);

  private:
	Spi *_spi;
};

#endif

